<?php

namespace Kangcg\Application\File;

class File
{
    /**
     * 删除文件或者文件夹
     * @param $path
     */
    public static function unlink($path, $isRemoveDir = true): bool
    {
        if (is_dir($path)) {
            $dn = opendir($path);
            while ($file = readdir($dn)) {
                if ($file == '.' || $file == '..') {
                    continue;
                }

                $file = $path . DIRECTORY_SEPARATOR . $file;
                self::unlink($file);
            }

            return self::unlinkDir($path);
        }

        return self::unlinkFile($path);
    }

    public static function unlinkFile($path): bool
    {
        return unlink($path);
    }

    public static function unlinkDir($dirPath): bool
    {
        return rmdir($dirPath);
    }

    /**
     * 读取文件夹里面的文件含路径
     * @param $path
     * @return array
     */
    public static function readDirPath($path)
    {
        $data = [];
        if (file_exists($path)) {
            $dn = opendir($path);
            while ($file = readdir($dn)) {
                if ($file == '.' || $file == '..') {
                    continue;
                }

                $filePath = $path . DIRECTORY_SEPARATOR . $file;
                if (is_dir($filePath)) {
                    $data[$file] = self::readDir($filePath);
                } else {
                    $data[] = $filePath;
                }
            }
        }

        return $data;
    }

    /**
     * 文件锁
     * @param string $filePath
     * @param \Closure $closure
     * @return false|mixed
     */
    public static function fileLock(string $filePath, \Closure $closure)
    {
        $bool = false;
        $file = fopen($filePath, 'w');
        if (flock($file, LOCK_EX)) {
            $bool = $closure();
            flock($file, LOCK_UN);
        }

        fclose($file);
        return $bool;
    }

    /**
     * 文件移动
     * @param string $form 要移动的原文件
     * @param string $to 移动的目标位置
     * @return bool
     */
    public static function move($form, $to): bool
    {
        if (!$toDir = dirname($to)) {
            return false;
        }

        $toDir = trim($toDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        if (is_dir($toDir) === false) {
            mkdir($toDir, 0775, true);
        }

        if (!file_exists($form)) {
            return false;
        }

        if (rename($form, $to) === false) {
            return false;
        }

        return true;
    }

    /**
     * 文件拷贝
     * @param string $form 源文件地址
     * @param string $to 目标文件地址
     * @param bool $isDelete 是否删除源文件
     * @return bool
     */
    public static function copy(string $form, string $to, bool $isDelete = false): bool
    {
        if (!$toDir = dirname($to)) {
            return false;
        }

        $toDir = trim($toDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
        if (is_dir($toDir) === false) {
            mkdir($toDir, 0775, true);
        }

        if (!file_exists($form)) {
            return false;
        }

        if (copy($form, $to) === false) {
            return false;
        }

        !$isDelete or unlink($form);
        return true;
    }

    /**
     * 文件写入
     * @param string $filePath
     * @param string $content
     * @return bool
     */
    public static function write(string $filePath, string $content): bool
    {
        $file = fopen($filePath, 'w');
        if (flock($file, LOCK_EX)) {
            $bool = fwrite($file, $content);
            flock($file, LOCK_UN);
        }

        fclose($file);
        if ($bool === false) {
            return false;
        }

        return true;
    }

    public static function getContent(string $filePath)
    {
        $content = null;
        if (!file_exists($filePath)) {
            return $content;
        }

        if ($size = filesize($filePath)) {
            $file = fopen($filePath, 'r');
            if (flock($file, LOCK_SH)) {
                $content = fread($file, $size);
                flock($file, LOCK_UN);
            }

            fclose($file);
        }

        return $content;
    }
}
